<template>
  <div class="uploadSinglePicture">
    <span v-show="$.isEmpty(value) && imgSize != null" class="tips">尺寸{{ imgSize }}</span>
    <el-upload ref="upload" :action="url" accept=".png,.jpg,.jpeg,.gif" :name="name" :headers="headers"
      :on-success="uploadSuccess" :on-error="uploadError" :on-progress="uploadProcess" :before-upload="checkUploadFile"
      :show-file-list="false" v-show="$.isEmpty(value)" v-if="!disabled">
      <el-button>上传图片</el-button>
    </el-upload>
    <el-progress :style="{ width: width }" v-show="progressFlag" :percentage="loadProgress"></el-progress>
    <div class="picture" :style="{ width: width, height: width }" v-show="$.isNotEmpty(value)">
      <div class="del" @click.stop="removePictures()" v-show="!disabled">
        <el-icon>
          <Close />
        </el-icon>
      </div>
      <el-image :style="{ width: imgWidth, height: imgWidth }" :src="value" :preview-src-list="[value]"
        :preview-teleported="true">
        <template #placeholder>
          <div :style="{ width: imgWidth, height: imgWidth }" class="image_placeholder">加载中</div>
        </template>
      </el-image>
    </div>
  </div>
</template>
<script setup>
import $ from "@util/base"
import { defineProps, ref, defineEmits, computed, watch } from "vue";
import { UPLOAD_URL } from "@net/url"
import auth from "@net/auth"
import msg from "@ui/message"
import { ReadBase64Dimension } from "@util/image-dimension"
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
  // 上传地址
  url: {
    type: String,
    default: UPLOAD_URL,
  },
  // 上传文件字段名
  name: {
    type: String,
    default: "file_data",
  },
  fileSize: {
    type: Number,
    default: null,
  },
  imgSize: {
    type: String,
    default: null
  },
  disabled: {
    type: Boolean,
    default: false
  },
  width: {
    type: Number,
    default: 100
  },
  modelValue: {
    type: String
  }
});

const width = props.width + 'px'
const imgWidth = props.width - 15 + 'px'

const progressFlag = ref(false)
const loadProgress = ref(0)

const value = ref(props.modelValue)

watch(() => props.modelValue, val => {
  value.value = props.modelValue
})


function uploadProcess(event) {
  progressFlag.value = true
  loadProgress.value = parseInt(event.percent);

  if (loadProgress.value >= 100) {
    loadProgress.value = 99

  }
}

function checkUploadFile(rawFile) {
  if (process.env.NODE_ENV === "production" && (props.imgSize != null || props.fileSize != null)) {
    return new Promise((res, rej) => {
      loadFile(rawFile, fileBase64 => {
        if (props.fileSize != null && rawFile.size > props.fileSize) {
          msg.error("图片大小以超过" + fileSizeText(props.fileSize))
          rej()
          return
        }
        if (props.imgSize != null) {
          let imgSizes = props.imgSize.split("×")
          let width = imgSizes[0]
          let height = imgSizes[1]
          let type = rawFile.name.substring(rawFile.name.lastIndexOf(".") + 1, rawFile.name.length)
          let imgWH = ReadBase64Dimension(fileBase64, type)

          if (imgWH.width != width || imgWH.height != height) {
            msg.error("图片尺寸错误，应为" + props.imgSize)
            rej()
            return
          }
        }
        res()
      })
    })
  } else {
    return true
  }
}

function loadFile(file, callback) {
  var reader = new FileReader();
  reader.onload = function (e) {
    callback(e.target.result)
  }
  reader.readAsDataURL(file)
}

function fileSizeText(value) {
  return parseInt(value / 1024) + "kb"
}

const upload = ref(null)
const headers = { accessToken: auth.getToken() }

function uploadSuccess(response) {
  loadProgress.value = 100
  progressFlag.value = false
  if (response.code === 0) {
    value.value = response.data.fileUrl
    emit('update:modelValue', value.value)
  } else {
    let err = ''
    if ($.isNotEmpty(response.msg)) {
      err = "：" + response.msg
    }
    msg.error("图片上传失败" + err)
  }
}
function uploadError() {
  msg.error("图片上传失败")
}
function removePictures() {
  value.value = null
  emit('update:modelValue', null)
  upload.value.clearFiles();
}

</script>

<style lang="scss" scoped>
.uploadSinglePicture {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  .tips {
    color: #606266;
    font-size: 12px;
  }
}

.image_placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--el-fill-color-light);
  color: var(--el-text-color-secondary);
  width: 120px;
  height: 120px;
}

.picture {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;

  &:hover {
    .del {
      display: block;
    }
  }

  .del {
    display: none;
    cursor: pointer;
    z-index: 2;
    top: 0;
    right: 0;
    background-color: #fc443e;
    color: #fff;
    position: absolute;
    width: 20px;
    height: 20px;
    line-height: 25px;
    text-align: center;
    border-radius: 50%;
  }
}
</style>
 